package cs3343.project.family;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import javax.swing.JOptionPane;

import cs3343.project.family.UI.GameFrame;

/**
 * The Class RoleController.
 */
public class RoleController {
	
	/** The gc. */
	private GameController gc;
	
	/** The character controller. */
	private CharacterController characterController;
	
	/** The card controller. */
	private CardController cardController;
	
	/** The ui controller. */
	private UIController uiController;
	
	/** The statistics controller. */
	private StatisticsController statisticsController;
	
	/** The roles. */
	private Role[] roles;
	
	/**
	 * Instantiates a new role controller.
	 *
	 * @param gc the gc
	 */
	public RoleController(GameController gc) {
		this.gc = gc;
		characterController = this.gc.getCharacterController();
		cardController = this.gc.getCardController();
		uiController = this.gc.getUiController();
		statisticsController = this.gc.getStatisticsController();
	}
	
	/**
	 * Identify role name.
	 *
	 * @param roleInput the role input
	 * @return the string
	 */
	public String identifyRoleName(String roleInput) {
		if (roleInput.equals("[MUM]"))
			return ConfigManager.getLangString("roleMum");
		else if (roleInput.equals("[DAD]"))
			return ConfigManager.getLangString("roleDad");
		else if (roleInput.equals("[GPA]"))
			return ConfigManager.getLangString("roleGPA");
		else if (roleInput.equals("[GMA]"))
			return ConfigManager.getLangString("roleGMA");
		else if (roleInput.equals("[BRO]"))
			return ConfigManager.getLangString("roleBro");
		else if (roleInput.equals("[SIS]"))
			return ConfigManager.getLangString("roleSis");
		return null;
	}
	
	/**
	 * Import role.
	 */
	public void importRole() {
		roles = new Role[ConfigManager.MAX_ROLE];
		
		String result[];
		try {
	        BufferedReader infile = new BufferedReader(new InputStreamReader(
	        		new FileInputStream(ConfigManager.getRolePath()), "UTF-8"));
	        String str;
	        int id = 0;
	        
	        while ((str = infile.readLine()) != null) 
	        {	        	
	        	if (str.length() > 0) {
                    // UTF - 8 BOM CHAR
                    int c = str.charAt(0);
                    if (c == 65279)
                    	str = str.substring(1, str.length());
	        	}
	            result = str.split("\t");
	            Role role = new Role(id, result[0], result[1], result[2], Integer.parseInt(result[3]));
	            roles[id++] = role;
	        }
	        infile.close();
	    } 
	    catch (IOException e) {
	    	ConfigManager.saveErrorLog(e.toString());
	    }
	}
	
	/**
	 * Assign all role.
	 */
	public void assignAllRole() {
		int i = 0;		
		while (!isFullyAssigned()) {
			int ran = (int) (ConfigManager.MAX_ROLE * Math.random());

			if (!roles[ran].getIsAssigned()) {
				characterController.getPlayer(i).setRole(roles[ran]);
				characterController.getPlayer(i).setEsteem((roles[ran]).getInitEsteem());
				roles[ran].setIsAssigned(true);
				i++;
			}
		}
	}
	
	/**
	 * Checks if is fully assigned.
	 *
	 * @return true, if is fully assigned
	 */
	public boolean isFullyAssigned() {
		for (int i = 0; i < characterController.getNumOfPlayer(); i++)
			if (characterController.getPlayer(i).getRole() == null)
				return false;
		return true;
	}
	
	/**
	 * Sets the role function button text.
	 */
	public void setRoleFunctionButtonText() {
		String role = characterController.getCurrentPlayer().getRole().getRoleName();
		GameFrame gf = uiController.getGameFrame();
		
		if (role.equals("[MUM]") || role.equals("[BRO]") ||role.equals("[SIS]") || role.equals("[GMA]")) {
			gf.setRoleFunctionButton(ConfigManager.getLangString("btnRolePassive"), false);
			
		}
		else if (role.equals("[DAD]")) {
			if (gc.getRound() % 3 == 0 && gc.getRound() != 0) {
				gf.setRoleFunctionButton(ConfigManager.getLangString("btnGetToolCard"), true);
			}
			else {
				gf.setRoleFunctionButton(ConfigManager.getLangString("btnAbilityNA"), false);
			}			
		}
		else if (role.equals("[GPA]")) {
			if (gc.getRound()%2 == 0 && gc.getRound() != 0) {
				gf.setRoleFunctionButton(ConfigManager.getLangString("transferSE"), true);
			}
			else {
				gf.setRoleFunctionButton(ConfigManager.getLangString("abilityNA"), false);
			}
		}
	}
	
	//for ACTIVE application by pressing role function button in GrameFrame
	/**
	 * Apply current role function.
	 */
	public void applyCurrentRoleFunction() {
		String role = characterController.getCurrentPlayer().getRole().getRoleName();
		
		if (role.equals("[DAD]"))
			dadRoleFunction();
		else if (role.equals("[GPA]"))
			gpaRoleFunction();
	}
	
	//check and apply passive role function
	/**
	 * Passive role function.
	 */
	public void passiveRoleFunction() {
		String role = characterController.getCurrentPlayer().getRole().getRoleName();
		
		if (role.equals("[MUM]"))
			mumRoleFunction();
		else if (role.equals("[GMA]"))
			gmaRoleFunction();
	}
	
	//[MUM]	家用能力	每5回合累積自尊值10點，當自尊值不足10點時自動取得累積的自尊值
	/**
	 * Mum role function.
	 */
	public void mumRoleFunction() {		
		int oriMumCounter = gc.getMumCounter();
		
		if (gc.getRound() % 3 == 0 && gc.getRound() != 0 && !gc.getMumAdded()) {
			int newMumCounter = gc.getMumCounter() + 10;
			gc.setMumCounter(newMumCounter);
			gc.setMumAdded(true);
		}
		
		if (characterController.getCurrentPlayer().getEsteem() <= 10 && oriMumCounter!= 0) {
			int oriEsteem = characterController.getCurrentPlayer().getEsteem();
			gc.updateEsteem(characterController.getCurrentPlayer(), oriEsteem += gc.getMumCounter(), "使用角色技能 " + characterController.getCurrentPlayer().getRole().getEffectName());
			gc.setMumCounter(0);
			
			JOptionPane.showMessageDialog(null, String.format(ConfigManager.getLangString("msgRoleMum"),  
					oriMumCounter,
					characterController.getCurrentPlayer().getEsteem()));
		}
	}

	//[BRO]	運動能力	若摘中六點，可多摘一次
	/**
	 * Bro role function.
	 *
	 * @return true, if successful
	 */
	public boolean broRoleFunction() {
		String role = characterController.getCurrentPlayer().getRole().getRoleName();
		
		if (role.equals("[BRO]"))
			if (gc.getDice().rollDice(1, 6) == 6) {
				statisticsController.addplayerLog(characterController.getCurrentPlayer(), "使用角色技能 " + characterController.getCurrentPlayer().getRole().getEffectName());
				JOptionPane.showMessageDialog(null, ConfigManager.getLangString("msgRoleBro"));
				return true;
			}
		return false;
	}
	
	//[DAD]	投資能力	每三回合可選擇以50點自尊值換取工具咭一張
	/**
	 * Dad role function.
	 */
	public void dadRoleFunction() {
		int oriEsteem = characterController.getCurrentPlayer().getEsteem();
		gc.updateEsteem(characterController.getCurrentPlayer(), oriEsteem -= 50, "使用角色技能 " + characterController.getCurrentPlayer().getRole().getEffectName());
		
		int ranCard = (int) (cardController.getNumOfMagicToolCard() * Math.random() + 1);
		Card card = cardController.getMagicToolCard(String.valueOf(ranCard));
		
		JOptionPane.showMessageDialog(null, String.format(ConfigManager.getLangString("msgRoleDad"),  
											card.getName(),
											card.getDescription()));
		
		characterController.getCurrentPlayer().addCard(card);
		gc.afterPressed();
	}
	
	/**
	 * Gpa role function.
	 */
	public void gpaRoleFunction() {
		String initName = "";

	    //JDialog.setDefaultLookAndFeelDecorated(true);
	    Object[] playerSelection = new Object[characterController.getNumOfPlayer() - 1];
	    for (int i = 0, j = 0; i < characterController.getNumOfPlayer(); i++) {
	    	if (!characterController.getPlayer(i).getName().equalsIgnoreCase(characterController.getCurrentPlayer().getName())) {
	    		playerSelection[j] = characterController.getPlayer(i).getName();
	    		if (j == 0)
	    			initName = characterController.getPlayer(i).getName();
	    		j++;
	    	}
	    }
	    
	    String initialSelection = initName;
	    Object selection = JOptionPane.showInputDialog(null, ConfigManager.getLangString("msgChoosePlayer"),
	    		ConfigManager.getLangString("msgChoosePlayerTitle"), JOptionPane.QUESTION_MESSAGE, null, playerSelection, initialSelection);

	    if (selection != null) {
	    	for (int i = 0; i < characterController.getNumOfPlayer(); i++)
	    		if (characterController.getPlayer(i).getName().equalsIgnoreCase(String.valueOf(selection))) {
	    			characterController.getPlayer(i).addEsteem(100);
	    			characterController.getCurrentPlayer().minusEsteem(100);
	    		}
	    	
	    	statisticsController.addplayerLog(characterController.getCurrentPlayer(), "使用角色技能 " + characterController.getCurrentPlayer().getRole().getEffectName());
	    	JOptionPane.showMessageDialog(null, String.format(ConfigManager.getLangString("msgRoleGPA"), String.valueOf(selection)));
	    	gc.afterPressed();
	    }	    
	    else
	    	JOptionPane.showMessageDialog(null, ConfigManager.getLangString("msgRoleGPAfail"));
	}
	
	//[GMA]	免罰能力	每三合可免一次扣自尊值的懲罰
	/**
	 * Gma role function.
	 */
	public void gmaRoleFunction() {		
		if (gc.getOriSE() > gc.getNewSE() && !gc.getGmaPenaltySkipped() 
				&& gc.getRound()%3 == 0 && gc.getRound() != 0) {
			gc.updateEsteem(characterController.getCurrentPlayer(), gc.getOriSE(), "使用角色技能 " + characterController.getCurrentPlayer().getRole().getEffectName());
			gc.setGmaPenaltySkipped(true);
			JOptionPane.showMessageDialog(null, ConfigManager.getLangString("msgNoPenalty"));
		}
	}
	
	//[SIS]	動作能力	完成動作卡可能雙倍自尊值
	/**
	 * Sis role function.
	 */
	public void sisRoleFunction() {
		String role = characterController.getCurrentPlayer().getRole().getRoleName();
		
		if (role.equals("[SIS]")) {
			if(gc.getNewSE() > gc.getOriSE()) {
				characterController.getCurrentPlayer().addEsteem(10);
				statisticsController.addplayerLog(characterController.getCurrentPlayer(), "使用角色技能 " + characterController.getCurrentPlayer().getRole().getEffectName());
				JOptionPane.showMessageDialog(null, ConfigManager.getLangString("msgRoleSis"));
			}
		}
	}
	
	/**
	 * Gets the all roles.
	 *
	 * @return the all roles
	 */
	public Role[] getAllRoles() {
		return roles;
	}
}
